<?php

namespace App\Providers;

use Illuminate\Cache\RateLimiting\Limit;
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\RateLimiter;
use Illuminate\Support\Facades\Route;
use Illuminate\Support\Str;

class RouteServiceProvider extends ServiceProvider
{
    /**
     * The path to your application's "home" route.
     *
     * Typically, users are redirected here after authentication.
     *
     * @var string
     */
    const HOME = '/home';

    protected $namespace = 'App\Http\Controllers';

    protected $api_namespace = 'App\Http\Controllers\Api';

    protected $admin_namespace = 'App\Http\Controllers\Admin';

    protected $chat_namespace = 'App\Http\Controllers\Chat';
//    protected $master_namespace = 'App\Http\Controllers\Master';

    protected $default_action = 'index';//默认的action

    /**
     * Define your route model bindings, pattern filters, and other route configuration.
     */
    public function boot(): void
    {
        $this->configureRateLimiting();

        $this->routes(function () {
            Route::prefix('api/api')
                ->middleware('api')
                ->namespace($this->namespace)
                ->group(base_path('routes/api.php'));
            Route::middleware('web')
                ->namespace($this->namespace)
                ->group(base_path('routes/web.php'));
            Route::prefix('api/admin')
                ->middleware('admin')
                ->namespace($this->admin_namespace)
                ->group(base_path('routes/admin.php'));
            Route::prefix('api/chat')
                ->middleware('chat')
                ->namespace($this->chat_namespace)
                ->group(base_path('routes/chat.php'));
//            Route::prefix('api/master')
//                ->middleware('master')
//                ->namespace($this->master_namespace)
//                ->group(base_path('routes/master.php'));
        });
    }

    /**
     * Register any application services.
     *
     * @return void
     */
    public function register()
    {
        $this->booted(function () {
            $this->setRootControllerNamespace();

            if ($this->routesAreCached()) {
                $this->loadCachedRoutes();
            } else {
                $this->loadRoutes();
                $this->app->booted(function () {
                    $this->app['router']->getRoutes()->refreshNameLookups();
                    $this->app['router']->getRoutes()->refreshActionLookups();
                });
            }
            $this->app->booted(function () {
                $this->reorganizationRoutes();
            });
        });
    }

    /**
     * 路由重组
     */
    protected function reorganizationRoutes()
    {

        Route::namespace($this->namespace)->group(function (\Illuminate\Routing\Router $route) {

            $request = request();
            $requestUri = $request->server->get('REQUEST_URI');

            if (strpos($requestUri, '?')) {
                $requestUri = strstr($requestUri, "?", true);
            }

            if (str_starts_with($requestUri, '/')) {
                $requestUri = substr($requestUri, 1);
            }

            $args = explode('/', $requestUri);
            $args = array_map([Str::class, 'studly'], $args);             //下划线转大写

            if ($args[0] == "Api") {
                array_shift($args);                                     //去掉最前面的API
            }
            $action = array_pop($args);
            $id = null;
            if (is_numeric($action)) {
                $id = $action;
                $action = array_pop($args);

            }
            $action = count($args) >= 2 ? $action : $this->default_action;// 默认进入index
            $action = lcfirst($action);
            $start = lcfirst(array_shift($args));
            $class = ucfirst(implode('\\', $args));
            defined('ACTION_NAME') ?: define('ACTION_NAME', $action);
            defined('MODULE_NAME') ?: define('MODULE_NAME', $start);

            switch (strtoupper($start)){

                case 'ADMIN':
                    $this->adminroute($class, $this->admin_namespace, $action, $id, $requestUri, $route);
                    break;
                case 'API':
                    $this->apiroute($class, $this->api_namespace, $action, $id, $requestUri, $route);
                    break;
                case 'CHAT':
                    $this->chatroute($class, $this->api_namespace, $action, $id, $requestUri, $route);
                    break;
//                case 'MASTER':
//                    $this->masterroute($class, $this->master_namespace, $action, $id, $requestUri, $route);
//                    break;

            }


        });
    }

    /**
     * Configure the rate limiters for the application.
     *
     * @return void
     */
    protected function configureRateLimiting()
    {
        RateLimiter::for('api', function (Request $request) {
            return Limit::perMinute(300)->by($request->user()?->id ?: $request->ip());
        });
    }

    /**
     * @param string $class
     * @param string $namespace
     * @param string $action
     * @param int|string $id
     * @param mixed $requestUri
     */
    protected function adminroute(string $class, string $namespace, string $action, mixed $id, mixed $requestUri, \Illuminate\Routing\Router $route): void
    {
        //判断是哪个端
//        config(["auth.defaults.guard" => 'admin']);
        if (!empty($class) && method_exists($namespace . '\\' . $class . 'Controller', $action)) {
//                    Route::any($requestUri, "\\" . $namespace . "\\" . $class . 'Controller@' . $action)->middleware(['admin','jwt.auth', 'view.route', 'permission']);

            $middleware = ['admin', 'jwt.auth', 'permission'];
            if (isset($id)) {
                $action =  $namespace . "\\" . $class . 'Controller@' . $action;
                if(!$route->getRoutes()->getByAction(trim($action,"\\"))){
                    Route::any(substr($requestUri, 0, strrpos($requestUri, '/')) . '/{id}', $action)->middleware($middleware);
                }
            } else {
                $action =  $namespace . "\\" . $class . 'Controller@' . $action;
                if(!$route->getRoutes()->getByAction(trim($action,"\\"))){
                    Route::any($requestUri, $action)->middleware($middleware);
                }
            }
        }
    }    /**
 * @param string $class
 * @param string $namespace
 * @param string $action
 * @param int|string $id
 * @param mixed $requestUri
 */
    protected function apiroute(string $class, string $namespace, string $action, mixed $id, mixed $requestUri, \Illuminate\Routing\Router $route): void
    {
        //判断是哪个端
//        config(["auth.defaults.guard" => 'api']);
        if (!empty($class) && method_exists($namespace . '\\' . $class . 'Controller', $action)) {
//                    Route::any($requestUri, "\\" . $namespace . "\\" . $class . 'Controller@' . $action)->middleware(['admin','jwt.auth', 'view.route', 'permission']);
            $middleware = ['api','jwt.auth'];
            if (isset($id)) {
                $action =  $namespace . "\\" . $class . 'Controller@' . $action;
                if(!$route->getRoutes()->getByAction(trim($action,"\\"))){
                    Route::any(substr($requestUri, 0, strrpos($requestUri, '/')) . '/{id}', $action)->middleware($middleware);
                }
            } else {
                $action =  $namespace . "\\" . $class . 'Controller@' . $action;
                if(!$route->getRoutes()->getByAction(trim($action,"\\"))){
                    Route::any($requestUri, $action)->middleware($middleware);
                }
            }
        }
    }
    protected function chatroute(string $class, string $namespace, string $action, mixed $id, mixed $requestUri, \Illuminate\Routing\Router $route): void
    {
        //判断是哪个端
        if (!empty($class) && method_exists($namespace . '\\' . $class . 'Controller', $action)) {
//                    Route::any($requestUri, "\\" . $namespace . "\\" . $class . 'Controller@' . $action)->middleware(['admin','jwt.auth', 'view.route', 'permission']);
            $middleware = ['chat', 'jwt.auth','chat.guards'];
            if (isset($id)) {
                $action =  $namespace . "\\" . $class . 'Controller@' . $action;
                if(!$route->getRoutes()->getByAction(trim($action,"\\"))){
                    Route::any(substr($requestUri, 0, strrpos($requestUri, '/')) . '/{id}', $action)->middleware($middleware);
                }
            } else {
                $action =  $namespace . "\\" . $class . 'Controller@' . $action;
                if(!$route->getRoutes()->getByAction(trim($action,"\\"))){
                    Route::any($requestUri, $action)->middleware($middleware);
                }
            }
        }
    }
}
